﻿/*********************************************************************
 *
 *                             NOTICE
 *               COPYRIGHT (c) 2012 Panoscopix Software, Inc.
 *                UNPUBLISHED - ALL RIGHTS RESERVED
 * 
 *      This program is confidential, proprietary, and a trade
 *   secret of Panoscopix Software, Inc. The receipt or possession of
 *     this program does not convey any rights to reproduce or
 *      disclose its contents, or to manufacture, use, or sell
 *       anything that it may describe, in whole or in part, 
 *   without the specific written consent of Panoscopix Software, Inc.
 *
 * Command class for "touching" a file, i.e., creating a file.
 * 
 *******************************************************************/
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using FileSystem;

namespace FileSystem.Impl.Commands
{
	class ChangeDir : ICommand, ICommandPrototype, INodeVisitor
	{
		private static ChangeDir zombie;
	
		private static void loadEmulator() {

            zombie = new ChangeDir(new HelpDescription() { Name="cd", Description="Changes directory." });
			ICommandPrototypeRegistry r = AppResources.getInstance().getCommandRegistry();
			r.register("cd", zombie);
		}
	
		private IFSDirectory cwd;
		private String dirName;
		private bool executeSucceeded;
		private IResult lastResult;
        private IHelpDescription helpDescription;

        private ChangeDir(IHelpDescription helpDescription)
        {
            this.helpDescription = helpDescription;
		}

		private ChangeDir(String dirName)
		{
			this.dirName = dirName;
			executeSucceeded = false;
		}
	
		public ICommand clone() {
			//Cannot clone touch without name of file as arg.
			return null;
		}
	
		public ICommand clone(String arg) {
			ChangeDir rc = new ChangeDir(arg);
			return rc;
		}

        public IHelpDescription Description
        {
            get
            {
                return this.helpDescription;
            }
        }

		public IResult execute() {
            this.cwd = AppResources.getInstance().getFileSystem().CurrentDirectory;

			if (this.dirName == "..")
			{
				if(this.cwd.getParent() != null)
				{
					AppResources.getInstance().getFileSystem().CurrentDirectory = this.cwd.getParent();
					executeSucceeded = true;
					lastResult = new Result("cd successful: " + this.dirName);
				}
				else
				{
					executeSucceeded = true;
					lastResult = new Result("Cannot go above root directory");
				}
				
			}
			else
			{
				IFSNode node = cwd.GetByName(this.dirName);
				lastResult = null;
				executeSucceeded = false;

				if (node != null)
				{
					node.Accept(this);
				}
				else
				{
					lastResult = new Result(true, "Given directory could not be found.");
				}
			}

			return lastResult;
		}
	
		public void undo() {
			if (!executeSucceeded) {
				//nothing to do, because execution failed...
				//we don't want to remove the node that might have been there of the same name.
				return;
			}
			AppResources.getInstance().getFileSystem().CurrentDirectory = cwd;
		}
	
		public IResult redo() {
			return execute();
		}
	
		public String describe(IPrintContext context) {
			return context.getFormattedString("mkdir " + dirName + "(" + executeSucceeded + ").");
		}

		#region INodeVisitor Members

		public void VisitFile(IFSFile file)
		{
			lastResult = new Result(true, "Given name is not a directory");
			executeSucceeded = false;
		}

		public void VisitDirectory(IFSDirectory directory)
		{
			AppResources.getInstance().getFileSystem().CurrentDirectory = directory;
			executeSucceeded = true;
			lastResult = new Result("cd successful: " + directory.describe());
		}

		public void VisitLink(IFSLink link)
		{
			if (link.GetLinkedNode() != null)
			link.GetLinkedNode().Accept(this);
		}

		#endregion
	}
}
